<template>
  <div class="machine full-height bg-white page-content content relative-position transparent-tips"
       style="padding-bottom: 20px">
    <!-- 搜索区 -->
    <collapse ref="collapse">
      <template v-slot:content>
        <div class="form-inline bottom" style="justify-content: space-between; padding: 6px 20px 0;">
          <div class="left box" style="display: flex">
            <div class="row">
              <select-tree label="所在位置" :sel-tree="queryParams.location" class="margin-r-20 margin-b-10"
                           ref="selectTree"
                           :tree-list="locationOptions" node-key="hash" @treeChange="_changeTreeNode"/>
              <q-select
                class="select multipe-select margin-r-20 margin-b-20"
                multiple
                outlined dense emit-value map-options options-dense
                ref="multipeSelect"
                @input="selDevice"
                :options="deviceOptions"
                v-model="queryParams.deviceIds"
              >
                <q-tooltip v-if="queryParams.deviceIds.length > 0">
                      <span v-for="(item,index) in queryParams.deviceIds" :key="index">
                        <span v-if="item == 'all'">全部 </span>
                        <span v-else>{{ findOption(item) }} </span>
                      </span>
                </q-tooltip>
                <template v-slot:option="scope">
                  <q-item v-bind="scope.itemProps" v-on="scope.itemEvents">
                    <q-item-section>
                      <q-item-label v-html="scope.opt.label"></q-item-label>
                    </q-item-section>
                    <!--                    <q-item-section side>-->
                    <!--                      <q-item-label v-html="scope.opt.assetNumber" />-->
                    <!--                    </q-item-section>-->
                  </q-item>
                </template>
                <template v-slot:no-option>
                  <div class="no-option"/>
                </template>
                <template v-slot:before>
                  <span class="form-name">设备:</span>
                </template>
              </q-select>
              <q-select
                class="select margin-r-20 margin-b-20"
                outlined dense emit-value map-options options-dense
                :options="statusOptionsAll"
                v-model="queryParams.status"
              >
                <template v-slot:no-option>
                  <div class="no-option"/>
                </template>
                <template v-slot:before>
                  <span class="form-name">机台状态:</span>
                </template>
              </q-select>
              <yz-input v-model="queryParams.managementStatus"
                        inputType="select"
                        class="margin-b-20 margin-r-20"
                        :options="otherStatusOptionsAll"
                        title="管理状态"
              />
              <select-tooltip v-model="queryParams.processStatus"
                              isShowAll
                              :multiple='false'
                              v-if="hasPermission"
                              :options="processStatus"
                              msg="作业状态"/>
            </div>
          </div>
          <div style="display: flex">
            <q-btn
              class="btn margin-r-10"
              outline
              color="primary"
              @click="resetSearch"
              label="重置"
            />
            <q-btn class="btn" unelevated type="submit" color="primary" label="查询" @click="searchList()"/>
            <!--            <q-btn class="btn" unelevated type="submit" color="primary" label="查询" @click="pagination.page = 1; pagination.rowsPerPage = 15; searchList()"/>-->
          </div>
        </div>
      </template>
    </collapse>
    <!-- 搜索区End -->
    <div class="flex justify-end" style="padding: 0 20px">
      <legend-box :is-init="true"/>
    </div>
    <div class="text-center text-grey-6 padding-20" v-if="!tableData.length">暂无数据</div>
    <!-- 卡片列表 -->
    <q-scroll-area ref="scrollTargetRef" style="margin: 0 10px;flex: 1;padding-top: 10px" :thumb-style="thumbStyle">
      <q-infinite-scroll :offset="250" :scroll-target="$refs.scrollTargetRef" ref="scrollTarget">
        <div style="height: 5px"></div>
        <div class="row flex">
          <div class="card-item col-lg-card col-md-4 col-sm-6" v-for="(item, index) in tableData" :key="index">
            <div style="padding: 0 5px">
              <div class="card" @click="routerTo(item)"
                   v-stat="{id:CommonConfig.statData.machine.detail.id,name:CommonConfig.statData.machine.detail.name}">
                <div class="flex items-center justify-between" style="display:-webkit-flex;display:flex">
                  <div class="flex items-center device-name font-size-14 text-weight-bold text-ellipsis"
                       style="width: calc(100% - 100px)">
                    {{ item.name && item.assetNumber ? `${item.name}(${item.assetNumber})` : '--' }}
                    <q-tooltip>{{
                        item.name && item.assetNumber ? `${item.name}(${item.assetNumber})` : '--'
                      }}
                    </q-tooltip>
                  </div>
                  <div class="time-box text-center text-white font-size-14"
                       :style="{ backgroundColor: judgeStatus(item.status, 'color') }">
                    {{ `${judgeStatus(item.status, 'name')}:${item.statusDuration}${item.statusDurationUnit}` }}
                  </div>
                </div>
                <div class="bor-b relative-position" :class="[showCount ? '': 'bor-n']" style="line-height: 18px;padding: 10px 0">
                  <div class="full-width" style="padding-right: 60px">
                    <div class="full-width text-ellipsis">
                      操作人员：{{ item.operatorName ? item.operatorName : '--' }}
                      <q-tooltip>{{ item.operatorName ? item.operatorName : '--' }}</q-tooltip>
                    </div>
                    <div class="full-width text-ellipsis">
                      技术人员：{{ item.technicianName ? item.technicianName : '--' }}
                      <q-tooltip>{{ item.technicianName ? item.technicianName : '--' }}</q-tooltip>
                    </div>
                    <div class="full-width text-ellipsis">
                      设备型号：{{ item.model ? item.model : '--' }}
                      <q-tooltip>{{ item.model ? item.model : '--' }}</q-tooltip>
                    </div>
                  </div>
                  <div class="absolute-top-right" style="width: 48px;height: 24px">
                    <div class="state-box bg-white flex justify-between items-center" style="margin: 8px 0 4px">
                      <div :style="{ backgroundColor: judgeStatus(item.coverStatus, 'other') }"></div>
                      <div :style="{ backgroundColor: judgeStatus(item.faultStatus,  'other') }"></div>
                      <div :style="{ backgroundColor: judgeStatus(item.repairStatus, 'other') }"></div>
                    </div>
                    <div style="width: 100%;padding: 0" class="text-right full-width">
                      <div class="text-warning" style="display: inline;" v-show="item.news > 0">
                        <q-icon class="iconfont icontubiao-78 font-size-12"
                                style="margin-right: 5px;vertical-align: top"></q-icon>
                        <span style="line-height: 22px">{{ item.news > 10 ? '10+' : item.news }}</span>
                      </div>
                    </div>
                  </div>
                </div>
                <div class="flex justify-between">
                  <div v-if="topicType" style="line-height: 1.7;margin-top: 5px; width: 80%" class="text-ellipsis">加工产品：
                    {{ item.materialNamesAndNumbers }}
                    <q-tooltip>{{ item.materialNamesAndNumbers }}</q-tooltip>
                  </div>
                  <div v-if="topicType" style="width: 20%;text-align: right;position: relative"
                       @mouseenter="linkEnter(item)" @mouseleave="leaveLink(item)">
                    <q-icon class="iconfont icontubiao5-15 font-size-12" :style="{color: item.linkShow ? '#999999': 'rgb(153, 153, 153, 0.5)'}"></q-icon>
                    <div class="link-btn-container" v-show="item.linkShow">
                      <div class="link-btn border-btn" @click.stop="goDetail(item, 1)">加工工单</div>
                      <div class="link-btn" @click.stop="goDetail(item, 2)">质检工单</div>
                    </div>
                  </div>
                </div>
                <div v-if="topicType" class="flex items-center">
                  <div style="line-height: 1.7; width: calc(100% - 38px)" class="text-ellipsis">产品规格：
                    {{ item.specs }}
                  </div>

                  <data-list :dataList="item.productSpecs" v-if="item.specs !== '--'"/>
                </div>

                <div v-if="topicType" style="line-height: 1.7; width: 100%" class="text-ellipsis">工序名称：
                  {{item.processName}}
                  <q-tooltip>{{item.processName}}</q-tooltip>
                </div>
<!--                <div style="line-height: 1.7" class="text-ellipsis">程序号：{{ item.programName }}-->
<!--                  <q-tooltip>{{ item.programName }}</q-tooltip>-->
<!--                </div>-->
                <template v-if="topicType">
                  <div style="line-height: 1.7" class="text-ellipsis">计划进度：{{
                      `${item.finishedCount}/${item.jobCount}`
                    }}
                    <q-tooltip>{{ `${item.finishedCount}/${item.jobCount}` }}</q-tooltip>
                  </div>
                  <div style="line-height: 1.7" class="flex items-center justify-between">
                    <div class="flex-1 text-ellipsis">
                      当前应完成数：{{ `${item.expectedCount}` }}
                      <q-tooltip>当前应完成数：{{ `${item.expectedCount}` }}</q-tooltip>
                    </div>
                    <div style="width: 100px" class="text-ellipsis text-right">
                      {{
                        getDifferenceCount(item.expectedCount, item.finishedCount, item.jobCount, item.processName).label
                      }}：
                      {{ getDifferenceCount(item.expectedCount, item.finishedCount, item.jobCount, item.processName).value }}
                      <q-tooltip>{{
                          getDifferenceCount(item.expectedCount, item.finishedCount, item.jobCount, item.processName).label
                        }}：{{ getDifferenceCount(item.expectedCount, item.finishedCount, item.jobCount, item.processName).value }}
                      </q-tooltip>
                    </div>
                  </div>
                  <div class="progress-bar">
                    <div class="progress-detail"
                         :class="{'serious': getDifferenceCount(item.expectedCount, item.finishedCount, item.jobCount, item.processName).label === '严重落后', 'slight': getDifferenceCount(item.expectedCount, item.finishedCount, item.jobCount, item.processName).label === '稍微落后'}"
                         :style="{'width': item.actualProgress <= 0 ? 0 : (item.actualProgress > 100 ? 100 : item.actualProgress) + '%'}"/>
                    <div class="tips"
                         :class="{'backward': getDifferenceCount(item.expectedCount, item.finishedCount, item.jobCount, item.processName).label.indexOf('落后') > -1}"
                         :style="{'left': item.progress>100?100:item.progress + '%'}"/>
                  </div>
                </template>
                <template v-else-if="showCount">
                  <div style="line-height: 1.7" class="flex items-center justify-between">
                    <div class="text-ellipsis">
                      当日产量：{{ `${item.finishedCount}` }}
                    </div>
                  </div>
                  <div class="progress-bar">
                    <div class="progress-detail" style="width: 0"></div>
                    <div class="tips" style="left:0"></div>
                  </div>
                </template>
              </div>
            </div>
          </div>
        </div>
      </q-infinite-scroll>
    </q-scroll-area>
  </div>
</template>

<script>
import Collapse from '../../components/collapse/index'
import SelectTree from 'src/components/select-tree'
import {
  getOrganize,
  getDevices,
  getMachineStatusList,
  getProcessCount,
  getTodayProductivity,
  getAllDevice
} from 'src/boot/status-monitor/machine'
import { defaultSchemesClearer } from '../../assets/js/util'
// import { getDict } from '../../boot/common/dict'
import { mapActions, mapGetters } from 'vuex'
import _ from 'lodash'
import { getCustomerSet } from '../../boot/system/customer-set'
import legendBox from './components/legend'
import roleMenuApi from '../../boot/system/role-menu'
import dataList from './components/detail-list'

export default {
  name: 'stats-monitor',
  computed: {
    ...mapGetters([
      'userInfo',
      'client',
      'statusList',
      'productionVal'
    ]),
    otherStatusOptionsAll () {
      const all = {
        value: null,
        label: '全部'
      }
      return [all, ...this.otherStatusOptions]
    },
    statusOptionsAll () {
      const all = {
        value: null,
        label: '全部'
      }
      return [all, ...this.statusList]
    },
    // 是否显示当日产量
    // 当没有车间id查询设备的时候, 无法查询当日产量, 因此如果查全部不显示产量
    showCount () {
      return this.queryParams.location.id !== '-1'
    },
    // 是否可选择所有设备
    showAllDevice () {
      // 太仓中集
      return this.userInfo.tenant_id === '51112124626481152'
    }
  },
  components: {
    Collapse,
    SelectTree,
    legendBox,
    dataList
  },
  data () {
    return {
      topicType: null, // 是否开通生产模块（0无，1有）
      // 滚动条样式
      thumbStyle: this.CommonConfig.thumbStyle,
      // 搜索条件
      searchBy: '',
      // 搜索值
      keyword: '',
      // 主表格分页配置
      // pagination: {
      //   // 当前页码
      //   page: 1,
      //   // 每页条数
      //   rowsPerPage: 15,
      //   // 总条数
      //   rowsNumber: 0
      // },
      // 所在位置数据源
      locationOptions: [],
      // 设备数据源
      deviceOptions: [{
        value: 'all',
        label: '全部'
      }],
      // 状态源数据
      statusOptions: [],
      // 查询条件
      queryParams: {
        processStatus: 'all', // 作业状态
        location: {
          id: null,
          level: null,
          label: '',
          hash: ''
        }, // 所在位置
        station: null,
        deviceIds: ['all'], // 工位
        status: null,
        managementStatus: null
      },
      workshopId: '',
      currentWorkShopId: '', // 当前的workshopId
      tableData: [], // 列表数据
      // 前一次的设备id数组用于取消订阅
      oldId: [],
      // mqtt定时器
      // timerMqtt: null,
      // 查询定时器
      timerGetList: null,
      timerTime: null,
      duration: 0,
      isInit: true,
      otherStatusOptions: [], // 管理状态详细
      processStatus: [], // 作业状态
      allDevicesList: [], // 所有设备详细
      deviceOptionsDetail: {}, // 设备详细
      hasPermission: false,
      productionAlarm: 0,
      productionWarning: 0,
      getProductivity: null
    }
  },

  created () {
    // 初始化查询列表
    // this.init()
    // 初始化mqtt
    this.onSubscribe()
    this.saveCustomerSet()
    // this.getCustomData()
  },

  mounted () {
    // 每60秒重新订阅一次mqtt防止订阅失效
    // this.timerMqtt = setInterval(this.onConnect, 60000)
    // 每3分钟重新查询列表以更新应完成产量
    this.timerGetList = setInterval(this.searchList, 300000)
    this.timerTime = setInterval(this.updateDuration, 1000)
    this.getProductivity = _.throttle((msgBoxId, index) => {
      getTodayProductivity(this.workshopId, msgBoxId).then(res => {
        if (res.data) {
          this.$set(this.tableData[index], 'finishedCount', res.data.productivity)
        }
      })
    }, 2000)
  },

  beforeDestroy () {
    // 清除定时器
    clearInterval(this.timer)
    clearInterval(this.timerGetList)
    if (this.timerLoading !== void 0) {
      clearTimeout(this.timerLoading)
      this.$q.loading.hide()
    }
    clearInterval(this.timerTime)
    // 取消订阅
    this.closeUbscribeTopic()
  },
  beforeRouteEnter (to, from, next) {
    next(vm => {
      // // 每次进入页面刷新
      // vm.isInit = true
      vm.saveCustomerSet()
      if (to.name === 'statsMonitor' && from.name === 'statusOverview' && !_.isEmpty(to.params)) {
        vm.isInit && vm.init(to.params)
        !vm.isInit && vm.setSearchData(to.params)
      } else {
        vm.isInit && vm.init()
        !vm.isInit && vm.searchList()
      }
    })
  },
  beforeRouteLeave (to, from, next) {
    this.closeUbscribeTopic()
    next()
  },

  methods: {
    ...mapActions([
      'saveCustomerSet'
    ]),
    hasCraftMenu (type) {
      // 从状态中获取租户Id
      const tenantId = this.userInfo.tenant_id
      // 获取租户所购买的所有系统视图
      roleMenuApi.getCompanyView(tenantId, 'pc').then(res => {
        this.hasPermission = _.indexOf(res.data, this.Enums.SYS_PERMISSION.CRAFT_MENU.value) !== -1
        this.hasPermission && type && (this.queryParams.processStatus = type)
        !this.hasPermission && (this.queryParams.processStatus = 'all')
      })
    },
    // 设置搜索项
    setSearchData (params) {
      this.queryParams.status = null
      this.queryParams.managementStatus = null
      this.hasCraftMenu(params.type)
      this.queryParams.location = this.getLocation(this.locationOptions, params)
      this.$refs.selectTree.setValue(this.queryParams.location)
      this._changeTreeNode(this.queryParams.location, true)
      // this.searchList()
    },
    // 获取客制化设置
    getCustomData () {
      getCustomerSet().then(response => {
        this.productionAlarm = response.productionAlarm
        this.productionWarning = response.productionWarning
      })
    },
    // 选择设备触发
    selDevice: function (details) {
      const selItem = this.queryParams.deviceIds.find(item => {
        return item === 'all'
      })
      if (details[details.length - 1] === 'all') {
        if (selItem) {
          this.queryParams.deviceIds = ['all']
        }
      } else {
        if (selItem) {
          const selList = this.queryParams.deviceIds.splice(this.queryParams.deviceIds.length - 1)
          this.queryParams.deviceIds = selList
        }
      }
      if (this.queryParams.deviceIds.length === 0) {
        this.queryParams.deviceIds = ['all']
      }
    },
    // 获取设备名称
    findOption (item) {
      for (let i in this.deviceOptions) {
        // eslint-disable-next-line eqeqeq
        if (item == this.deviceOptions[i].value) {
          return this.deviceOptions[i].label
        }
      }
    },
    /**
     * FIXME 有工具函数，迭代重构时记得直接调用工具函数
     * 时分秒转换
     * @param {number} second
     * @return {{}}
     */
    getDuration (second = 0) {
      if (second >= 0 && second < 60) {
        let seconds = second
        return {
          duration: seconds,
          unit: '秒'
        }
      } else if (second >= 60 && second < 3600) {
        let minutes = Math.floor(parseInt(second) / 60)
        return {
          duration: minutes,
          unit: '分'
        }
      } else if (second >= 3600 && second < (3600 * 24)) {
        let hours = Math.floor(parseInt(second) / 3600)
        return {
          duration: hours,
          unit: '时'
        }
      } else {
        let days = Math.floor(parseInt(second) / (3600 * 24))
        return {
          duration: days,
          unit: '天'
        }
      }
    },

    /**
     * 获取实际预计差值
     * @param {number} expectedCount 预计完成数量
     * @param {number} finishedCount 实际完成数量
     * @param {number} jobCount 总计划数
     * @return {{}}
     */
    getDifferenceCount (expectedCount, finishedCount, jobCount, processName) {
      let label = ''
      let value = null
      // 若预计产量大于总数
      // 返回总数-预计的绝对值
      if (Number(expectedCount) > Number(jobCount)) {
        value = Math.abs(Number(jobCount) - Number(finishedCount))
      } else {
        // 若预计产量小于总数
        // 返回预计-实际的绝对值
        value = Math.abs(Number(expectedCount) - Number(finishedCount))
      }
      if (Number(expectedCount) > 0) {
        const percent = (Number(expectedCount) - Number(finishedCount)) / Number(expectedCount)
        if (percent <= this.productionVal.min / 100) {
          label = '进度正常'
        } else if (percent > this.productionVal.min / 100 && percent < this.productionVal.max / 100) {
          label = '稍微落后'
        } else if (percent >= this.productionVal.max / 100) {
          label = '严重落后'
        } else {
          label = '暂未派工'
        }
      } else {
        if (processName) {
          label = '进度正常'
        } else {
          label = '暂未派工'
        }
      }

      return {
        value: String(value).indexOf('.') > -1 ? value.toFixed(1) : value,
        label: label
      }
    },

    /**
     * FIXME 现在是按定时器每秒增加 应改为当前时间-开始时间
     * 计时器，用来增加每种状态秒数
     */
    updateDuration () {
      this.tableData.forEach(o => {
        o.oldSecond = Number(o.oldSecond) + 1
        o.statusDuration = this.getDuration(o.oldSecond).duration
        o.statusDurationUnit = this.getDuration(o.oldSecond).unit
      })
    },

    /**
     * 初始化数据
     */
    init (params = null) {
      let statusOptions = [{
        label: '全部',
        value: null
      }]
      let otherStatusOptions = []
      // 冲状态枚举中取出机场状态数组
      const newArr = Object.entries(this.Enums.MACHINES_STATUS)
        .map(entry => {
          return {
            value: entry[1].value,
            label: entry[1].desc,
            color: entry[1].color
          }
        })
      newArr.forEach((item, index) => {
        if (index < 5) {
          statusOptions.push({
            value: item.value,
            label: item.label,
            color: item.color
          })
        } else {
          otherStatusOptions.push({
            value: item.value,
            label: item.label,
            color: item.color
          })
        }
      })
      this.statusOptions = statusOptions
      this.otherStatusOptions = otherStatusOptions
      // 冲状态枚举中取出机场状态数组
      const processStatus = Object.entries(this.Enums.PROCESS_STATUS)
        .map(entry => {
          return {
            value: entry[1].value,
            label: entry[1].desc
          }
        })
      this.processStatus = processStatus
      this.locationOptions = []
      // this.equipmentTypeOptions = []
      this.hasCraftMenu(params ? params.type : null)
      // 获取组织机构树
      getOrganize().then(res => {
        // 去除 default 节点
        let clearTree = defaultSchemesClearer.clear(res.data)

        // 重新组织 tree
        clearTree.forEach(reorganize)

        function reorganize (node) {
          // 为节点添加唯一键，用于 tree 组件标识唯一节点
          node.uniqueKey = node.level + ':' + node.id

          if (node.children instanceof Array) {
            node.children.forEach(reorganize)
          }
        }
        // 定制需求, 需要显示设备
        if (this.showAllDevice) {
          clearTree.unshift({ id: '-1', hash: '-1', label: '全部' })
        }
        this.locationOptions = clearTree
        if (params) {
          this.queryParams.location = this.getLocation(clearTree, params)
        } else {
          this.queryParams.location = Object.assign({}, clearTree[0])
        }

        this.$refs.selectTree.setValue(this.queryParams.location)

        this._changeTreeNode(this.queryParams.location)
      })
    },
    getLocation (list, params) {
      let location = list[0]
      params.workshopId && (location = _.cloneDeep(list).find(item => item.id === params.workshopId))
      params.lineId !== 'all' && (location = _.cloneDeep(location.children).find(item => item.id === params.lineId))
      return location
    },
    /**
     * 订阅并发送消息
     */
    onSubscribe () {
      if (this.client) {
        this.tableData.forEach(item => {
          this.client.subscribe(
            `${this.CommonConfig.socketConfig.SOCKET_TOPIC.statusTopic.subscribeTopic}${item.id}`, this.onMessageArrived, { id: `statusTopic_${item.id}` }
          )// 订阅主题（机床状态）
          if (this.topicType) { // 开通生产模块
            this.client.subscribe(
              `${this.CommonConfig.socketConfig.SOCKET_TOPIC.realTimeCount.subscribeTopic}${item.id}`, this.onMessageArrived, { id: `realTimeCount_${item.id}` }
            )// 订阅主题（实时报工总数）
          } else {
            this.client.subscribe(
              `${this.CommonConfig.socketConfig.SOCKET_TOPIC.normalWorkpiece.subscribeTopic}${item.id}`, this.onMessageArrived, { id: `normalWorkpiece_${item.id}` }
            )// 订阅主题（当日计数）
          }
        })
      } else {
        setTimeout(() => {
          this.onSubscribe()
        }, 200)
      }
    },

    /**
     * 接受盒子返回消息
     * @param {string} message
     */
    onMessageArrived (message) {
      // 分割topic
      let msgBoxIds = message.headers.destination.split('/')
      // 序列化返回msg
      let msg = JSON.parse(message.body).data
      // 获取boxId
      let msgBoxId = msgBoxIds[5]
      // 判断返回的msg是否为状态的msg
      const tableData = _.cloneDeep(this.tableData)
      const index = _.findIndex(tableData, o => o.id + '' === msgBoxId)
      const changeItem = tableData[index]
      // 状态相关
      if (msgBoxIds[4] === 'status') {
        if (msg.alarmCount !== null && msg.alarmCount !== undefined) {
          this.$set(this.tableData[index], 'news', msg.alarmCount)
        }
        // 1加工
        // 非报警状态
        if (msg.statusCode !== this.Enums.MACHINES_STATUS.WARNING.value) {
          // 非加工状态 单次加工循环数量清零
          if (msg.statusCode !== this.Enums.MACHINES_STATUS.MACHINING.value) {
            this.$set(this.tableData[index], 'oneCycleCount', 0)
          } else {
            // 当切换为加工状态时（并且前次状态不为加工状态）
            if (changeItem.status !== this.Enums.MACHINES_STATUS.MACHINING.value) {
              // 请求后台，获取单次加工循环数量
              getProcessCount(changeItem.boxId, changeItem.id).then(res => {
                this.$set(this.tableData[index], 'oneCycleCount', res.data.oneCycleCount)
              })
            }
          }
          // 换线的状态
          if (msg.statusCode === this.Enums.MACHINES_STATUS.CHANGEOVER.value) {
            this.$set(this.tableData[index], 'coverStatus', msg.statusCode)
          } else if (msg.statusCode === this.Enums.MACHINES_STATUS.BREAKDOWN.value) { // 故障状态
            const faultStatus = msg.overFlag ? null : msg.statusCode
            this.$set(this.tableData[index], 'faultStatus', faultStatus)
          } else if (msg.statusCode === this.Enums.MACHINES_STATUS.REPAIR.value) { // 维修状态
            const repairStatus = msg.overFlag ? null : msg.statusCode
            this.$set(this.tableData[index], 'repairStatus', repairStatus)
          } else { // 其它物理状态
            const oldSecond = Number(msg.duration)
            this.$set(this.tableData[index], 'oldSecond', oldSecond)
            const duration = this.getDuration(oldSecond)
            this.$set(this.tableData[index], 'statusDuration', duration.duration)
            this.$set(this.tableData[index], 'statusDurationUnit', duration.unit)
            this.$set(this.tableData[index], 'status', msg.statusCode)
          }
        }
      } else if (msgBoxIds[4] === 'normal_workpiece') { // 无生产模块获取当日计数
        // msg中的currentCount是自然日产量 且后端没法直接发送班制日产量 因此此处重新查询产量
        // !this.topicType && this.$set(this.tableData[index], 'finishedCount', msg.currentCount)
        if (!this.topicType) {
          if (this.workshopId) {
            this.getProductivity(msgBoxId, index)
          } else {
            this.$set(this.tableData[index], 'finishedCount', msg.currentCount)
          }
        }
      } else if (msgBoxIds[4] === 'realTimeCount') { // 有生产模块获取报工总数
        if (!this.topicType) { // 未开通生产模块不订阅
          return
        }
        // 循环次数(接收及覆盖)
        this.$set(this.tableData[index], 'finishedCount', msg.finishedCount)
        const progress = this.getProgress(this.tableData[index])
        this.$set(this.tableData[index], 'progress', progress.progress)
        this.$set(this.tableData[index], 'actualProgress', progress.actualProgress)
      }
    },

    /**
     * 取消订阅
     */
    closeUbscribeTopic () {
      this.oldId.forEach(id => {
        this.client.unsubscribe(`statusTopic_${id}`)
        if (this.topicType) { // 开通生产模块
          this.client.unsubscribe(`realTimeCount_${id}`)
        } else {
          this.client.unsubscribe(`normalWorkpiece_${id}`)
          // this.client.unsubscribe(`processCount_${id}`)
        }
      })
    },

    /**
     * 重置查询条件
     */
    resetSearch () {
      this.queryParams.location = Object.assign({}, this.locationOptions[0])
      this.$refs.selectTree.setValue(this.queryParams.location)
      this._changeTreeNode(this.queryParams.location, false)
      this.queryParams.status = null
      this.queryParams.managementStatus = null
      this.queryParams.processStatus = 'all'
    },
    // 获取进度
    getProgress (o) {
      if (o.jobCount) {
        if (!Number(o.jobCount)) {
          return {
            progress: 0,
            actualProgress: 0
          }
        }
        let progress = 0, actualProgress = 0
        if (Number(o.expectedCount) / Number(o.jobCount) * 100 <= 0) {
          progress = 0
        } else if (Number(o.expectedCount) / Number(o.jobCount) * 100 >= 100) {
          progress = 100
        } else {
          progress = Number(o.expectedCount) / Number(o.jobCount) * 100
        }
        if (Number(o.finishedCount) / Number(o.jobCount) * 100 <= 0) {
          actualProgress = 0
        } else if (Number(o.finishedCount) / Number(o.jobCount) * 100 >= 100) {
          actualProgress = 100
        } else {
          actualProgress = Number(o.finishedCount) / Number(o.jobCount) * 100
        }
        return {
          progress: progress,
          actualProgress: actualProgress
        }
      } else {
        return {
          progress: 0,
          actualProgress: 0
        }
      }
    },
    /**
     * 根据条件搜索
     */
    searchList () {
      if (this.$route.name !== 'statsMonitor') {
        return
      }
      this.$q.loading.show()

      if (!this.queryParams.deviceIds.length || !this.allDevicesList) {
        this.$message.warning('请选择设备')
        return
      }
      this.currentWorkShopId = this.workshopId
      let params = {}
      if (!_.isNil(this.queryParams.status)) {
        params['status'] = this.queryParams.status
      }
      if (!_.isNil(this.queryParams.managementStatus)) {
        params['managementStatus'] = this.queryParams.managementStatus
      }
      if (this.queryParams.deviceIds[0] === 'all') {
        params['deviceIds'] = _.map(_.cloneDeep(this.allDevicesList), 'id')
      } else {
        params['deviceIds'] = this.queryParams.deviceIds
      }
      this.queryParams.processStatus !== 'all' && (params['processStatus'] = this.queryParams.processStatus)
      getMachineStatusList(params, this.workshopId).then(res => {
        this.closeUbscribeTopic()
        this.topicType = res.data[0] ? res.data[0].topicType : null
        const listData = res.data.map(o => {
          // 开通生产模块，完工数量取总和
          const progressDetail = {}
          if (this.topicType) {
            const progress = this.getProgress(o)
            progressDetail.progress = progress.progress
            progressDetail.actualProgress = progress.actualProgress
          }
          const countKey = ['expectedCount', 'finishedCount', 'jobCount']
          const countList = {}
          countKey.forEach(key => {
            countList[key] = this.$utils.label(o[key], 0)
          })
          const labelKey = ['operatorName', 'technicianName', 'programName', 'deviceType', 'workOrderNumber']
          const labelList = {}
          labelKey.forEach(key => {
            labelList[key] = this.$utils.label(o[key])
          })

          const oldSecond = Number(this.$utils.label(o.statusDuration, 0))
          const device = this.deviceOptionsDetail[o.id]
          const duration = this.getDuration(oldSecond)
          const processName = this.$utils.label(o.processName)
          let specs = '--'
          if (!_.isNil(o.productSpecs)) {
            o.productSpecs.forEach(item => {
              if (item.productSpecs.length) {
                item.productSpecs.forEach(i => {
                  i.label = this.$utils.label(i.label)
                })
                item.specs = _.join(_.map(item.productSpecs, 'label'), ',')
              } else {
                item.specs = '--'
              }
              specs = _.join(_.map(o.productSpecs, 'specs'), ';')
            })
          }
          const data = {
            ...o,
            ...progressDetail,
            ...device,
            ...countList,
            ...labelList,
            boxId: device.boxStrId,
            oldSecond: oldSecond,
            repairStatus: o.repairStatus,
            statusDuration: duration.duration,
            statusDurationUnit: duration.unit,
            materialNamesAndNumbers: this.$utils.label(o.materialNamesAndNumbers),
            processName: _.isNil(o.processSort) ? processName : `${o.processSort + 1}-${processName}`,
            programName: this.$utils.label(o.programName),
            linkShow: false,
            specs: specs
          }
          return data
        })
        this.tableData = listData
        this.onSubscribe()
        this.oldId = []
        this.oldId = this.tableData.map(item => {
          return item.id
        })
        // this.pagination.rowsNumber = res.data.total
      }).finally(() => {
        this.$q.loading.hide()
      })
    },

    /**
     * 选择组织机构树节点
     * @param {number} val
     */
    _changeTreeNode: function (val, init = false) {
      if (val.id && val.label && val.hash) {
        this.queryParams.location.id = val.id
        this.queryParams.location.level = val.level
        this.queryParams.location.label = val.label
        this.queryParams.location.hash = val.hash
        // 获取设备
        this.workshopId = val.level === 2 ? val.id : val.workshopId
        if (val.id === '-1') {
          getAllDevice().then(res => {
            this.allDevicesList = res.data
            this.getDeviceOption(res.data)
          })
        } else {
          getDevices(val.level, val.id).then(res => {
            this.allDevicesList = res.data
            this.getDeviceOption(res.data)
          })
        }
      } else {
        this.queryParams.location = {
          id: null,
          level: null,
          label: '',
          hash: ''
        }
        this.queryParams.deviceIds = null
        this.deviceOptionsDetail = {}
        this.deviceOptions = []
      }
    },

    getDeviceOption (data, init) {
      const deviceOptions = []
      const deviceOptionsDetail = {}
      data.forEach(item => {
        deviceOptions.push({
          value: item.id,
          assetNumber: item.assetNumber,
          label: `${item.name}(${item.assetNumber})`
        })
        deviceOptionsDetail[item.id] = item
      })
      deviceOptions.unshift({
        value: 'all',
        label: '全部'
      })
      this.deviceOptions = deviceOptions
      this.deviceOptionsDetail = deviceOptionsDetail

      // 默认选择全部设备
      this.queryParams.deviceIds = ['all']
      if (this.isInit || init) {
        this.isInit = false
        this.searchList()
      }
    },

    /**
     * 过滤状态枚举
     * @param {number} statusCode
     * @param {string} type
     * @return {string}
     */
    judgeStatus (statusCode, type) {
      if (type === 'name') {
        let name = ''
        this.statusOptionsAll.forEach(o => {
          if (o.value === statusCode) {
            name = o.label
          }
        })
        return name
      } else if (type === 'color') {
        let color = ''
        this.statusOptionsAll.forEach(o => {
          if (o.value === statusCode) {
            color = o.color
          }
        })
        return color
      } else {
        let color = ''
        this.otherStatusOptions.forEach(o => {
          if (o.value === statusCode) {
            color = o.color
          }
        })
        return color
      }
    },

    /**
     * 跳转详情传值
     * @param {{}} val
     */
    routerTo (val) {
      const device = this.deviceOptionsDetail[val.id]
      this.$router.push({
        path: '/main/status-monitor-v3/machine-list/machine-detail',
        query: {
          id: val.id,
          // status: val.status,
          operatorName: val.operatorName,
          technicianName: val.technicianName,
          // oldSecond: val.oldSecond,
          boxId: val.boxId,
          boxStrId: val.boxStrId,
          boxUcloudNum: val.boxUcloudNum,
          // faultStatus: val.faultStatus,
          // repairStatus: val.repairStatus,
          // coverStatus: val.coverStatus,
          deviceInfo: val.deviceInfo,
          fromList: true,
          isPlc: device.isPlc || '0'
        }
      })
    },
    /**
     * 跳转按钮enter
     */
    linkEnter (item) {
      if (item.workOrderId) {
        item.linkShow = true
      }
    },
    leaveLink (item) {
      item.linkShow = false
    },
    /**
     * 跳转到加工工单或者质检工单
     * @param item
     * @param type 1 加工工单，2质检工单
     */
    goDetail (item, type) {
      if (type === 1) {
        const processParams = {
          workshopId: this.currentWorkShopId,
          orderId: item.workOrderId
        }
        this.$router.push({
          name: 'processOrder',
          params: processParams
        })
      } else if (type === 2) {
        const qualityParams = { workshopId: this.currentWorkShopId, orderId: item.workOrderId }
        this.$router.push({
          name: 'qualityOrder',
          params: qualityParams
        })
      }
    }
  }
}
</script>

<style scoped lang="stylus">
@media (min-width: 1440px) {
  .row > .col-lg-card {
    height: auto;
    width: 20%;
  }
}

>>> .q-select__dropdown-icon {
  width 24px
  height 24px
  font-size 24px
  color rgba(0, 0, 0, .54)
}

>>> .q-field--with-bottom {
  padding 0
}

>>> .q-field__marginal {
  font-size 16px
  color black
  font-weight 400
  text-align right
}

.card-item {
  padding 10px 5px

  .card {
    padding 10px
    box-shadow 0px 0px 7px 0px rgba(22, 22, 22, 0.2)
    border-radius 6px
    transition all 500ms ease-in-out
    -moz-transition all 500ms ease-in-out
    -webkit-transition all 500ms ease-in-out
    -o-transition all 500ms ease-in-out
    position relative
    display block
    cursor pointer

    .bor-b {
      border-bottom 1px solid #D3D3D3
    }

    .bor-n {
      border-bottom none;
    }

    .device-name {
      max-width calc(100% - 60px)
    }

    .time-box {
      width 96px
      height 24px
      border-radius 12px 0px 12px 12px
      line-height 24px
    }
  }

  .card:hover {
    top -10px
  }
}

.card-item:hover .card, .card-item:hover .state-box {
  top -10px
  background-color #ecefff !important
}

.progress-bar {
  width 100%
  height 14px
  background-color #d3d3d3
  border-radius 4px
  position relative
  margin-top 5px

  .progress-detail {
    height inherit
    background-color $secondary /* 不支持线性的时候显示 */
    background-image linear-gradient(to right, $secondary, #51a8e1, $primary);
    border-radius inherit

    &.serious {
      background-image linear-gradient(to right, #fe6d33, #f44941, #ec2449);
    }

    &.slight {
      background-image linear-gradient(to right, #e8d127, #f3bc19, #feac12);
    }
  }

  .tips {
    height inherit
    width 2px
    background-color $warning
    position absolute
    top 0
    transition left 200ms ease-in-out
    -moz-transition left 200ms ease-in-out
    -webkit-transition left 200ms ease-in-out
    -o-transition left 200ms ease-in-out

    &.backward {
      background-color $primary
    }
  }
}

.warning {
  width 52px
  margin-left 5px
  height 20px
  background rgba(255, 0, 0, 1)
  border-radius 10px
  line-height 20px
  padding 0 5px
}

.status {
  width: 10px
  height: 10px
  border-radius: 50%
  display: inline-block
  margin-right 5px
}

.text-warning {
  color #E43434 !important
}

.state-box {
  box-shadow 0px 0px 5px 0px rgba(0, 0, 0, 0.15)
  width 48px
  height 14px
  border-radius 7px
  padding 2px 5px

  div {
    width 10px
    height 10px
    background #d3d3d3
    box-shadow 0px 0px 3px 0px rgba(0, 0, 0, 0.15) inherit
    border-radius 50%

    &.light {
      box-shadow none
    }
  }
}

.link-btn-container {
  position: absolute;
  top: 20px;
  right: 0;
  width: 76px;
  height: 67px;
  background: #FFFFFF;
  box-shadow: 0px 0px 7px 0px rgba(22, 22, 22, 0.2);
  opacity: 0.94;
  border-radius: 6px;
  overflow: hidden
  z-index 5

  .link-btn {
    text-align center;
    line-height 33px;
    user-select: none;
  }

  .border-btn {
    border-bottom 1px solid #D3D3D3;
  }
}
</style>
